#ifdef KITSCHY_DEBUG_MEMORY 
#include "debug_memorymanager.h"
#endif

#ifdef WIN32
#include "windows.h"
#endif

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "pthread.h"

#include "BList.h"
#include "BVector.h"
#include "geometrics.h"
#include "quaternion.h"
#include "symbol.h"
#include "sort.h"
#include "ontology.h"
#include "featureterm.h"
#include "FTKBase.h"

#include "AWEntity.h"
#include "AWMessage.h"
#include "AWBrain.h"
#include "AWTracerBrain.h"
#include "AWThreadedBrain.h"
#include "AWNOOSBrain.h"
#include "AWNOOSLearnerBrain.h"

#include "CaseBaseUtils.h"

#include "loader.h"

#include "psm.h"



void AW_NOOSLearnerBrain::retain_cases(List<FeatureTerm> *cases,Symbol *strategy)
{
	List<FeatureTerm> l;
	FeatureTerm *c;

	write_debug_report("[Learner]: Applying retention strategy: %s with %i cases\n",strategy->get(),cases->Length());

	if (strategy->cmp("NR")) {
		// Never retain:
	} /* if */ 

	if (strategy->cmp("AR")) {
		// Always retain:
		l.Instance(*cases);
		l.Rewind();
		while(l.Iterate(c)) {
			m_casebase->AddFT(new FeatureTerm(c));
		} /* while */ 
	} /* if */ 

	if (strategy->cmp("OFR")) {
		// On Failure retain:
		FeatureTerm *s,*p,*s2;
		Symbol *an=new Symbol("foo");

		l.Instance(*cases);
		l.Rewind();
		while(l.Iterate(c)) {
			p=get_description(c);
			s=get_solution(c);
			s2=solve_problem_individually_without_IBA_cases(p,c->getSort(),an);
			if (!s->equivalents(s2)) {
				m_casebase->AddFT(new FeatureTerm(c));
				write_debug_report("[Learner]: case retained (%s %s)\n",s->getName()->get(),s2->getName()->get());
			} else {
				write_debug_report("[Learner]: case discarded\n");
			} /* if */ 
			delete p;
			delete s;
			delete s2;
		} /* while */ 

		delete an;
	} /* if */ 

	if (strategy->cmp("IDAL")) {
		// Informative-Disagreement for Active Learning retain:
		/* ... */ 
	} /* if */ 

} /* AW_NOOSLearnerBrain::retain_cases */ 


void AW_NOOSLearnerBrain::retain_case(FeatureTerm *c)
{
	List<FeatureTerm> *l;

	l=m_casebase->SearchFT(c->getName());

	if (l->Length()==0) {
		m_casebase->AddFT(c);
	} else {
		delete c;
		write_debug_report("[Learner]: Case being retained already present in case base\n");
	} /* if */ 

	while(!l->EmptyP()) l->ExtractIni();
} /* AW_NOOSLearnerBrain::retain_case */ 





FeatureTerm *AW_NOOSLearnerBrain::solve_problem_individually_without_IBA_cases(FeatureTerm *problem,Sort *sort,Symbol *agent_name)
{
	FeatureTerm *solution_record=0;
	Prediction *p=0;
	List<FeatureTerm> *cases=0;
	Path dp,sp;

	if (agent_name==0) {
		write_debug_report("[build_jers_without_IBA_cases]: no agent name provided!!!!!\n");
	} /* if */ 

	/* Retrieve precedents: */ 
	cases=m_casebase->SearchFT(sort);

	write_debug_report("[build_jers_without_IBA_cases]: solving with %i cases\n",cases->Length());

	/* Build description and solution paths: */ 
	dp.Add(new Symbol("description"));
	sp.Add(new Symbol("solution"));
	if (strcmp(problem->getSort()->get(),"sponge")==0) {
		sp.Add(new Symbol("order"));
	} /* if */ 
	
	/* call LID: */ 
	p=eva_LID(problem,cases,&dp,&sp,m_ontology,m_memory,1,0,1);
//	p=refinement_LID3(problem,cases,&dp,&sp,m_ontology,m_memory,1,0,1);

	while(!cases->EmptyP()) cases->ExtractIni();
	delete cases;

	/* build solution record: */ 
	write_debug_report("[build_jers_without_IBA_cases]: proposed %i JERs\n",p->solutions.Length());
	if (p->solutions.Length()==1) {
		solution_record=new FeatureTerm((char *)0,m_ontology->get_sort("problem-prediction"),4,
//										"problem",new FeatureTerm(p->problem),
										"solution",new FeatureTerm(p->solutions[0]),
										"support",new FeatureTerm((char *)0,*p->support[0],m_ontology),
										"justification",new FeatureTerm(p->justifications[0]),
										"agent",new FeatureTerm(0,new Symbol(agent_name),m_ontology));
	} else {
		int i;
		solution_record=FeatureTerm::SetFeatureTerm((Symbol *)0);

		for(i=0;i<p->solutions.Length();i++) {
			solution_record->addSetValue(new FeatureTerm((char *)0,m_ontology->get_sort("problem-prediction"),4,
//														 "problem",new FeatureTerm(p->problem),
														 "solution",new FeatureTerm(p->solutions[i]),
														 "support",new FeatureTerm((char *)0,*p->support[i],m_ontology),
														 "justification",new FeatureTerm(p->justifications[i]),
														 "agent",new FeatureTerm(0,new Symbol(agent_name),m_ontology)));
		} /* for */ 
	} /* if */ 

	delete p;
/*
	{
		char *str;
		str=solution_record->toStringNOOS(m_memory);
		write_debug_report("[AW_NOOSLearnerBrain]: solution:\n%s\n\n",str);
		delete []str;
	}
*/
	
	{
		List<FeatureTerm> individual_solutions;
		FeatureTerm *f,*f2;

		/* Solve the problem individually: */ 
		individual_solutions.Add(solution_record);

		/* Aggregate the solutions: */ 
		f=BWAV(&individual_solutions);
		f2=f->featureValue("solution");
		delete f;
		return f2;
	}
} /* AW_NOOSLearnerBrain::solve_problem_individually_without_IBA_cases */ 


